package org.example.service.impl;

import org.example.mapper.UserMapper;
import org.example.MyExecption.BusinessException;
import org.example.domain.User;
import org.example.myEnum.ErrorCode;
import org.example.service.LoginService;
import org.example.service.UserService;
import org.example.util.JwtTokenUtil;
import org.example.util.PasswordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    private static final Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);

    @Autowired
    UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserService userService;

    @Override
    public Map<String,Object> Login(User user) {
        try {
            logger.info("开始处理登录请求，用户名: {}", user.getUsername());
            
            if (user == null || user.getUsername() == null || user.getPassword() == null) {
                logger.warn("登录参数不完整");
                throw new BusinessException(ErrorCode.BAD_REQUEST);
            }
            
            //构建条件
            HashMap<String, Object> selectMap = new HashMap<>();
            selectMap.put("username", user.getUsername());
            
            //执行查询
            logger.debug("执行用户查询");
            List<User> users = userMapper.selectByMap(selectMap);

            //判断结果
            if (users == null || users.isEmpty()) {
                logger.warn("用户不存在: {}", user.getUsername());
                throw new BusinessException(ErrorCode.USER_NOT_FOUND);
            }

            //验证密码
            logger.debug("开始验证密码");
            if (!PasswordUtils.matches(user.getPassword(), users.get(0).getPassword())) {
                logger.warn("密码验证失败: {}", user.getUsername());
                throw new BusinessException(ErrorCode.USERNAME_PASSWORD_WRONG);
            }

            //生成token
            logger.debug("生成token");
            String token = JwtTokenUtil.generateToken(
                    users.get(0).getId().toString(),
                    users.get(0).getUsername()
            );

            // 更新最后登录时间
            User currentUser = users.get(0);
            currentUser.setLastLoginTime(new Date());
            userMapper.updateById(currentUser);

            //redis操作
            logger.debug("存储token到Redis");
            try {
                redisTemplate.opsForValue().set(
                        token,
                        users.get(0),
                        24,
                        TimeUnit.HOURS
                );
            } catch (Exception e) {
                logger.error("Redis存储token失败", e);
                // Redis失败不影响登录流程，继续执行
            }

            //返回用户信息
            users.get(0).setPassword(null);

            // 获取用户权限列表
            String permissions = userService.getUserPermissions(users.get(0).getId());

            Map<String,Object> returnMap = new HashMap<>();
            returnMap.put("token", token);
            returnMap.put("userInfo", users.get(0));

            logger.info("登录成功: {}", user.getUsername());
            return returnMap;
        } catch (BusinessException e) {
            // 业务异常直接抛出
            throw e;
        } catch (Exception e) {
            // 其他异常记录日志并转换为业务异常
            logger.error("登录过程中发生异常", e);
            throw new BusinessException(500, "系统繁忙，请稍后重试");
        }
    }

    @Override
    public void logout(Long userId) {
        try {
            logger.info("处理登出请求，用户ID: {}", userId);
            // 从请求头中获取token
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String token = request.getHeader("Authorization");
            if (token != null && token.startsWith("Bearer ")) {
                token = token.substring(7);
                // 直接删除token对应的数据
                redisTemplate.delete(token);
                logger.info("登出成功，删除token: {}", token);
            } else {
                logger.warn("未找到有效的token");
            }
        } catch (Exception e) {
            logger.error("登出过程中发生异常", e);
            throw new BusinessException(500, "系统繁忙，请稍后重试");
        }
    }
}
